package com.lzh.db.util;

/**
 * @author zhehen.lu
 * @date 2025/8/15 11:05
 */
public class TimeUniqueIdUtil {
    private volatile long lastTimestampSec = 0L;
    private volatile int sequence = 0;
    private final boolean isMillisecond;
    public static final TimeUniqueIdUtil secondId = new TimeUniqueIdUtil(false);
    public static final TimeUniqueIdUtil milliSecond = new TimeUniqueIdUtil(true);

    private TimeUniqueIdUtil(boolean isMillisecond) {
        this.isMillisecond = isMillisecond;
    }

    private long getCurrentTimeMillis() {
        return this.isMillisecond ? System.currentTimeMillis() : System.currentTimeMillis() / 1000L;
    }

    public synchronized String currentTimestampString(boolean addTimestamp, boolean addSeq) {
        long curTimestampSec = this.getCurrentTimeMillis();
        long diff = this.lastTimestampSec - curTimestampSec;
        if (diff > 0L) {
            throw new RuntimeException(String.format("当前时间戳比最后时间戳小 %d!", diff));
        } else {
            if (this.lastTimestampSec == curTimestampSec) {
                ++this.sequence;
                if (this.sequence > 999) {
                    while(this.getCurrentTimeMillis() == curTimestampSec) {
                    }

                    return this.currentTimestampString(addTimestamp, addSeq);
                }
            } else {
                this.sequence = 0;
                this.lastTimestampSec = curTimestampSec;
            }

            StringBuilder sb = new StringBuilder();
            if (addTimestamp) {
                sb.append(String.format("%d", this.lastTimestampSec));
            }

            if (addSeq) {
                sb.append(String.format("%03d", this.sequence));
            }

            return sb.toString();
        }
    }

    public long currentTimestampLong() {
        return Long.parseLong(this.currentTimestampString(true, true));
    }

    public long currentSequenceLong() {
        return Long.parseLong(this.currentTimestampString(false, true));
    }

}
